package cc.rengu.igas.bomp.core.service.trans;

import cc.rengu.igas.bomp.common.constant.BompAppParamConstant;
import cc.rengu.igas.bomp.common.constant.BompTreeNodeConstant;
import cc.rengu.igas.bomp.common.dao.BompTMMcFundInfoMapper;
import cc.rengu.igas.bomp.common.dao.MchntBaseInfoMapper;
import cc.rengu.igas.bomp.common.dao.impl.BompTMMcFundInfoMapperImpl;
import cc.rengu.igas.bomp.common.dao.impl.MchntBaseInfoMapperImpl;
import cc.rengu.igas.bomp.common.entity.BompTMMcFundInfo;
import cc.rengu.igas.bomp.common.entity.MchntBaseInfo;
import cc.rengu.igas.bomp.common.enums.BompTMMcFundInfoFundStatusEnum;
import cc.rengu.igas.bomp.common.enums.RespCodeEnum;
import cc.rengu.igas.bomp.facade.request.MompPaymentRequest;
import cc.rengu.igas.momp.facade.request.MchntMcPublishRequest;
import cc.rengu.jradp.mods.dbs.Database;
import cc.rengu.oltp.service.base.DubboAsynBaseService;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.dao.MchntOrderInfoMapper;
import cc.rengu.oltp.service.common.dao.PayOrderInfoMapper;
import cc.rengu.oltp.service.common.dao.UserOrderInfoMapper;
import cc.rengu.oltp.service.common.dao.impl.MchntOrderInfoMapperImpl;
import cc.rengu.oltp.service.common.dao.impl.PayOrderInfoMapperImpl;
import cc.rengu.oltp.service.common.dao.impl.UserOrderInfoMapperImpl;
import cc.rengu.oltp.service.common.entity.MchntOrderInfo;
import cc.rengu.oltp.service.common.entity.PayOrderInfo;
import cc.rengu.oltp.service.common.entity.UserOrderInfo;
import cc.rengu.oltp.service.common.enums.BizStatusEnum;
import cc.rengu.oltp.service.common.enums.ChannelEnum;
import cc.rengu.oltp.service.common.enums.OrderStatusEnum;
import cc.rengu.oltp.service.common.enums.TransStatusEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.realize.DubboService;
import cc.rengu.oltp.service.realize.OrderService;
import cc.rengu.oltp.service.realize.impl.DubboServiceImpl;
import cc.rengu.oltp.service.realize.impl.OrderServiceImpl;
import cc.rengu.oltp.utility.annotation.BIZ_PROCESS;
import cc.rengu.oltp.utility.util.ConvertUtil;
import cc.rengu.oltp.utility.util.DateUtil;
import cc.rengu.oltp.utility.util.XmlTreeUtil;
import cc.rengu.utility.reflect.JsonUtil;

import java.util.Arrays;
import java.util.List;

/**
 * @author Xuegui Cao
 * @date 2020/8/10
 * @description 营销打款-异步查证处理服务
 */
public class MompPaymentAsynCoreGeneralTransQueryService extends DubboAsynBaseService {

    @BIZ_PROCESS
    public void MompPaymentAsynCoreGeneralTransQueryService() throws Exception {
        rglog.debug("异步查证处理服务开始");
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        // TODO 判断查证结果
        String bizStatus = "";
        rglog.debug("查证结果：原交易状态<{}>", bizStatus);
        if (BizStatusEnum.FINISH.getStatus().equals(bizStatus)) {
            rglog.debug("查证成功,原交易成功.");
//            xmlTreeUtil.setXmlTreeStringValue(BompTreeNodeConstant.ESB_CHANNEL_SEQ_NUL, chnlOrigTxnInfo.getOrigChnlSeqNum());
        } else if (BizStatusEnum.PROCESSING.getStatus().equals(bizStatus)) {
            rglog.debug("查证超时.");
            return;
        } else {
            rglog.debug("查证成功,原交易失败.");
        }

        MompPaymentRequest mompPaymentRequest = new MompPaymentRequest();
        ConvertUtil.convertOutput(mompPaymentRequest);
        String instId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.INST_ID);
        String sysSeqNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);

        if (isUpdateOrderStatus(mompPaymentRequest, sysSeqNum, bizStatus)) {
            rglog.debug("更新订单表成功.");
        }
        if (isUpdateTMMcFundInfo(mompPaymentRequest.getUserId(), bizStatus)) {
            rglog.debug("更新打款记录表成功.");
        }
        rglog.debug("异步查证完成");

    }

    /**
     * 更改订单状态
     *
     * @param mompPaymentRequest 接口请求对象
     * @param sysSeqNum          交易流水号,用于查询原订单(正常打款时传系统流水号,查证后修改时传打款记录表中的打款流水号)
     * @param bizStatus          交易状态:BizStatusEnum
     * @return 更改结果, true-成功|false-失败
     * @throws Exception 异常信息
     */
    private boolean isUpdateOrderStatus(MompPaymentRequest mompPaymentRequest, String sysSeqNum, String bizStatus) throws Exception {
        rglog.info("开始更改订单状态,交易结果:<{}>", bizStatus);
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        // String sysSeqNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);
        String instId = mompPaymentRequest.getHeader().getInstId();
        String updateTime = DateUtil.getCurrentDateTime(BompAppParamConstant.yyyy_MM_dd_HHmmssSSS);

        //region 查询、更新 用户订单、商户订单、支付订单
        /*用户订单*/
        UserOrderInfoMapper userOrderInfoMapper = new UserOrderInfoMapperImpl();
        UserOrderInfo userOrderInfo = userOrderInfoMapper.selectUserOrderInfoByPrimaryKey(instId, sysSeqNum);
        if (userOrderInfo == null) {
            throw new BizException(RespCodeEnum.QUERY_DATA_IS_NULL.getRespCode(), RespCodeEnum.QUERY_DATA_IS_NULL.getRespDesc());
        }
        rglog.debug("查询用户订单:<{}>", JsonUtil.toJson(userOrderInfo));
        /*商户订单*/
        MchntOrderInfoMapper mchntOrderInfoMapper = new MchntOrderInfoMapperImpl();
        MchntOrderInfo mchntOrderInfo = mchntOrderInfoMapper.selectMchntOrderInfoByPrimaryKey(instId, sysSeqNum, mompPaymentRequest.getMchntNo());
        if (mchntOrderInfo == null) {
            throw new BizException(RespCodeEnum.QUERY_DATA_IS_NULL.getRespCode(), RespCodeEnum.QUERY_DATA_IS_NULL.getRespDesc());
        }
        rglog.debug("查询商户订单:<{}>", JsonUtil.toJson(mchntOrderInfo));
        /*支付订单*/
        PayOrderInfoMapper payOrderInfoMapper = new PayOrderInfoMapperImpl();
        List<PayOrderInfo> payOrderInfoList = payOrderInfoMapper.selectPayOrderInfoBySysSeqNum(instId, sysSeqNum);
        if (payOrderInfoList == null || payOrderInfoList.size() != 1) {
            throw new BizException(RespCodeEnum.QUERY_DATA_IS_NULL.getRespCode(), RespCodeEnum.QUERY_DATA_IS_NULL.getRespDesc());
        }
        PayOrderInfo payOrderInfo = payOrderInfoList.get(0);
        rglog.debug("查询支付订单:<{}>", JsonUtil.toJson(payOrderInfo));
        /*更新订单状态*/
        if (BizStatusEnum.FINISH.getStatus().equals(bizStatus)) {
            //成功
            userOrderInfo.setOrderStatus(OrderStatusEnum.FINISH.getStatus());
            userOrderInfo.setTransStatus(TransStatusEnum.TRANS_SUCC.getStatus());
            mchntOrderInfo.setTransStatus(TransStatusEnum.TRANS_SUCC.getStatus());
            payOrderInfo.setTransStatus(TransStatusEnum.TRANS_SUCC.getStatus());
            String channelSeqNum = xmlTreeUtil.getXmlTreeStringValue(BompTreeNodeConstant.ESB_CHANNEL_SEQ_NUL);
            payOrderInfo.setChannelSeqNum(channelSeqNum);

            /*商户服务平台调用时,打款成功更改营销活动状态为测试中*/
            String chanlId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.CHANNEL_ID);
            String mcNo = xmlTreeUtil.getXmlTreeStringValue("mcNo");
            if ("WECHAT".equals(chanlId) || "MOBILE".equals(chanlId) || "PCWEB".equals(chanlId)) {
                mchntMcPublish(mcNo);
            }
        } else if (BizStatusEnum.PROCESSING.getStatus().equals(bizStatus)) {
            //超时/未知
            userOrderInfo.setOrderStatus(OrderStatusEnum.INIT.getStatus());
            userOrderInfo.setTransStatus(TransStatusEnum.TRANS_TIMEOUT.getStatus());
            mchntOrderInfo.setTransStatus(TransStatusEnum.TRANS_TIMEOUT.getStatus());
            payOrderInfo.setTransStatus(TransStatusEnum.TRANS_TIMEOUT.getStatus());
        } else {
            //失败
            userOrderInfo.setOrderStatus(OrderStatusEnum.CLOSE.getStatus());
            userOrderInfo.setTransStatus(TransStatusEnum.SYSTEM_REJECT.getStatus());
            mchntOrderInfo.setTransStatus(TransStatusEnum.SYSTEM_REJECT.getStatus());
            payOrderInfo.setTransStatus(TransStatusEnum.SYSTEM_REJECT.getStatus());
        }
        userOrderInfo.setBizStatus(bizStatus);
        userOrderInfo.setUpdateTime(updateTime);

        mchntOrderInfo.setBizStatus(bizStatus);
        mchntOrderInfo.setUpdateTime(updateTime);

        payOrderInfo.setBizStatus(bizStatus);
        payOrderInfo.setUpdateTime(updateTime);
        //endregion

        OrderService orderService = new OrderServiceImpl();
        return orderService.updateOrderInfo(userOrderInfo, Arrays.asList(mchntOrderInfo), payOrderInfo);
    }

    /**
     * 更新营销打款记录表
     */
    private boolean isUpdateTMMcFundInfo(String userId, String transStatus) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String updateTime = DateUtil.getCurrentDateTime(BompAppParamConstant.yyyy_MM_dd_HHmmssSSS);
        BompTMMcFundInfo tmMcFundInfo = (BompTMMcFundInfo) xmlTreeUtil.getXmlTreeObjectValue("tmMcFundInfo", BompTMMcFundInfo.class);
        tmMcFundInfo.setUpdateTime(updateTime);
        String status;
        if (TransStatusEnum.TRANS_SUCC.getStatus().equals(transStatus)) {
            status = BompTMMcFundInfoFundStatusEnum.SUCCESS.getStatus();
        } else if (TransStatusEnum.SYSTEM_REJECT.getStatus().equals(transStatus)) {
            status = BompTMMcFundInfoFundStatusEnum.FAILURE.getStatus();
        } else {
            status = BompTMMcFundInfoFundStatusEnum.TIMEOUT.getStatus();
        }
        tmMcFundInfo.setFundStatus(status);
        tmMcFundInfo.setLastOprId(userId);
        BompTMMcFundInfoMapper bompTMMcFundInfoMapper = new BompTMMcFundInfoMapperImpl();
        int nResult = bompTMMcFundInfoMapper.updateTMMcFundInfo(tmMcFundInfo);
        if (nResult == Database.DBS_SUCCESS) {
            return true;
        }
        return false;
    }

    /**
     * 更改营销活动状态为测试中
     */
    private void mchntMcPublish(String mcNo) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String instId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.INST_ID);
        String sysSeqNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);
        String mchntNo = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.MCHNT_NO);
        DubboService dubboService = new DubboServiceImpl();
        MchntMcPublishRequest mchntMcPublishRequest = new MchntMcPublishRequest();
        cc.rengu.igas.momp.facade.base.Header mompHeader = new cc.rengu.igas.momp.facade.base.Header();
        ConvertUtil.convertOutput(mompHeader);
        mompHeader.setSrcSysId(AppParamConstant.SYS_ID);
        mompHeader.setChanlId(ChannelEnum.BSPS.getChannelType());
        mompHeader.setTxnNum("M00MO027");
        mompHeader.setTraceNo(sysSeqNum + "1");

        MchntBaseInfo mchntBaseInfo = (MchntBaseInfo) xmlTreeUtil.getXmlTreeObjectValue("mchntBaseInfo", MchntBaseInfo.class);
        if (null == mchntBaseInfo) {
            MchntBaseInfoMapper mchntBaseInfoMapper = new MchntBaseInfoMapperImpl();
            mchntBaseInfo = mchntBaseInfoMapper.selectMchntBaseInfoByPrimaryKey(instId, mchntNo);
        }
        mchntMcPublishRequest.setHeader(mompHeader);
        mchntMcPublishRequest.setQueryType("1");
        mchntMcPublishRequest.setQueryId(mchntNo);
        mchntMcPublishRequest.setQueryOrgId(mchntBaseInfo.getSignInstId());
        mchntMcPublishRequest.setQueryRole("10");
        mchntMcPublishRequest.setMcNo(mcNo);
        mchntMcPublishRequest.setOprType("4");

        int iReturnCode = dubboService.asynCallDubboService("manageMchntMcService", "publishMchntMc", mchntMcPublishRequest, "DubboAsynBaseService");
        if (iReturnCode != 0) {
            rglog.error("调用营销发布失败.");
        }
    }
}
